package com.xgpro.common.dingtalk.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiCallBackDeleteCallBackRequest;
import com.dingtalk.api.request.OapiCallBackRegisterCallBackRequest;
import com.dingtalk.api.response.OapiCallBackRegisterCallBackResponse;
import com.dingtalk.oapi.lib.aes.DingTalkEncryptor;
import com.dingtalk.oapi.lib.aes.Utils;
import com.xgpro.common.dingtalk.auth.AuthHelper;
import com.xgpro.common.dingtalk.service.contact.DDUserService;
import com.xgpro.common.results.PageResult;
import com.xgpro.common.results.ResponseResult;
import com.xgpro.domain.rolemanage.dto.UserDTO;
import com.xgpro.domain.rolemanage.entity.Token;
import com.xgpro.domain.talentintroduction.entity.User;
import com.xgpro.pc.rolemanage.service.TokenService;
import com.xgpro.pc.rolemanage.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

/**
 * @program: xgpro__dev
 * @description: 钉钉回调
 * @author: likai
 * @create: 2019-11-27 22:23
 **/

@RestController
public class RegisterController {

    @Value("${DD_ENV.APP_KEY}")
    private String APP_KEY;

    @Value("${DD_ENV.APP_SECRET}")
    private String APP_SECRET;
    @Value("${DD_ENV.CALL_URL}")
    private String CALL_URL;

    @Value("${DD_ENV.ENCODING_AES_KEY}")
    private String ENCODING_AES_KEY;

    @Value("${DD_ENV.TOKEN}")
    private String TOKEN;

    @Value("${DD_ENV.CORP_ID}")
    private String CORP_ID;

    @Resource
    private DDUserService ddUserService;

    @Resource
    private TokenService tokenService;

    @Resource
    private UserService userService;


    @RequestMapping("call_back")
    public void callBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("application/json; charset=utf-8");
        /** url中的签名 **/
        String msgSignature = request.getParameter("signature");
        /** url中的时间戳 **/
        String timeStamp = request.getParameter("timestamp");
        /** url中的随机字符串 **/
        String nonce = request.getParameter("nonce");

        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();

        try {
            DingTalkEncryptor dingTalkEncryptor = new DingTalkEncryptor(TOKEN, ENCODING_AES_KEY, CORP_ID);
            br = request.getReader();
            String str;
            while ((str = br.readLine()) != null) {
                sb.append(str);
            }
            br.close();
            /**
             * 从post请求的body中获取回调信息的加密数据进行解密处理
             */
            JSONObject jsonObject = JSON.parseObject(sb.toString());
            String encryptMsg = jsonObject.getString("encrypt");


            String plainText = dingTalkEncryptor.getDecryptMsg(msgSignature, timeStamp, nonce, encryptMsg);
            Map<String, Object> map = JSON.parseObject(plainText, Map.class);
            List<String> userIds = (List<String>) map.get("UserId");  //用户发生变更的userid列表
            System.out.println(userIds);
            /**
             * 根据回调数据类型做不同的业务处理
             */
            //1.获取token
            String accessToken = null;
            Token token = tokenService.findToken();
            if (token.getDate() != null && token.getToken() != null) {
                if ((new Date().getTime() - token.getDate().getTime()) <= (105 * 60 * 1000)) {
                    accessToken = token.getToken();
                } else {
                    accessToken = AuthHelper.getAccessToken(APP_KEY, APP_SECRET);
                    tokenService.update(new Date(), accessToken);
                }
            } else {
                accessToken = AuthHelper.getAccessToken(APP_KEY, APP_SECRET);
                tokenService.update(new Date(), accessToken);
            }

            String eventType = map.get("EventType").toString();

            PageResult<UserDTO> pageResult1 = null;
            User user = null;
            if (!"check_url".equals(eventType)) {
                if (!"user_leave_org".equals(eventType)) {
                    UserDTO userDTO = ddUserService.getUser(accessToken, userIds.get(0));
                    System.out.println("userDto"+userDTO);
                    user = new User();
                    BeanUtils.copyProperties(userDTO, user);

                    Map<String, Object> param = new HashMap<>();

                    //查询系统是否已经有该用户的信息，如果有，则进行更新，没有，则添加用户信息
                    param.put("userId", user.getUserId());
                    pageResult1 = userService.listUser(1, 1, param);
                    System.out.println("pageResult"+pageResult1);
                    if (!CollectionUtils.isEmpty(pageResult1.getRows())){
                        user.setId(pageResult1.getRows().get(0).getId());
                    }


                    System.out.println(user);
                }else {
                    Map<String, Object> param = new HashMap<>();

                    //查询系统是否已经有该用户的信息，如果有，则进行更新，没有，则添加用户信息
                    param.put("userId", userIds.get(0));
                    pageResult1 = userService.listUser(1, 1, param);
                }

            }


            switch (eventType) {
                case "user_add_org":
                    //通讯录用户增加
                    System.out.println("新增了一个用户");

                    if (CollectionUtils.isEmpty(pageResult1.getRows())) {
                        userService.addUser(user);
                    } else {

                        userService.updateUser(user);
                    }
                    break;
                case "user_modify_org":
                    //通讯录用户更改
                    System.out.println("修改了一个用户");
                    userService.updateUser(user);
                    break;
                case "user_leave_org":
                    //通讯录用户离职
                    System.out.println("删除了一个用户");
                    //存在用户，则删除用户的相关信息
                    if (!CollectionUtils.isEmpty(pageResult1.getRows())) {
                        userService.deleteUserInfo(pageResult1.getRows().get(0).getId());

                    }
                    break;

                case "check_url":
                    //测试回调接口事件类型

                    System.out.println("测试回调接口！");
                    break;
                default: // do something
                    break;
            }
            /**
             * 返回success的加密信息表示回调处理成功
             */
            Map<String, String> encryptedMap = dingTalkEncryptor.getEncryptedMap("success", System.currentTimeMillis(), Utils.getRandomStr(8));
            response.getWriter().append(JSON.toJSONString(encryptedMap));
        } catch (Exception e) {
            /**
             * 失败的情况，应用的开发者应该通过告警感知，并干预修复
             */
            System.err.println(e.getMessage());
            System.out.println("process callback failed！");
        } finally {
            if (br != null) {
                br.close();
            }
        }

    }


    @RequestMapping("/send_call_back")
    public ResponseResult sendCallBack() throws Exception {

        String accessToken = AuthHelper.getAccessToken(APP_KEY, APP_SECRET);
        /**
         * 先删除企业已有的回调
         */
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/call_back/delete_call_back");
        OapiCallBackDeleteCallBackRequest request = new OapiCallBackDeleteCallBackRequest();
        request.setHttpMethod("GET");
        client.execute(request, accessToken);
        client = new DefaultDingTalkClient("https://oapi.dingtalk.com/call_back/register_call_back");
        OapiCallBackRegisterCallBackRequest register = new OapiCallBackRegisterCallBackRequest();
        register.setUrl(CALL_URL);
        register.setAesKey(ENCODING_AES_KEY);
        register.setToken(TOKEN);
        register.setCallBackTag(Arrays.asList("user_add_org", "user_modify_org", "user_leave_org"));
        OapiCallBackRegisterCallBackResponse response = client.execute(register, accessToken);

        System.out.println("注册回调的结果是---------------" + response.getErrmsg());
        return ResponseResult.ok(response);
    }
}